package com.huike.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.huike.common.result.Result;
import com.huike.constants.JwtClaimsConstant;
import com.huike.constants.MessageConstant;
import com.huike.dto.LoginDto;
import com.huike.exception.AccountNotFoundException;
import com.huike.exception.PasswordErrorException;
import com.huike.exception.VerificationCodeErrorException;
import com.huike.mapper.SysUserMapper;
import com.huike.pojo.SysUser;
import com.huike.properties.JwtProperties;
import com.huike.service.UserService;
import com.huike.utils.JwtUtil;
import com.huike.utils.RedisCache;
import com.huike.utils.ValidateCodeUtil;
import com.huike.vo.LoginVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

@Service
public class UserServiceImp implements UserService {


    @Autowired
    private RedisCache redisCache;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private JwtProperties jwtProperties;

    /**
     * 生成图片验证码
     *
     * @param response
     */
    @Override
    public void getCodeImage(HttpServletResponse response) {
        try {
            int width = 110;
            int height = 40;
            BufferedImage verifyImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            String randomText = ValidateCodeUtil.drawRandomText(width, height, verifyImg);
            System.out.println("验证码" + randomText);
            redisCache.saveCache("code", randomText);

            response.setContentType("image/png");//必须设置响应内容类型为图片，否则前台不识别

            OutputStream os = response.getOutputStream(); //获取文件输出流

            ImageIO.write(verifyImg, "png", os);//输出图片流

            os.flush();

            os.close();//关闭流

        } catch (IOException e) {

            System.out.println(e.getMessage());

            e.printStackTrace();

        }
    }

    /**
     * 用户登录
     *
     * @param loginDto
     * @return
     */
    @Override
    public Result<LoginVo> userLogin(LoginDto loginDto) {
        String userName = loginDto.getUserName();
        String password = loginDto.getPassword();
        String code = loginDto.getCode();

        if (code == null) {
            //验证码为空
            throw new VerificationCodeErrorException(MessageConstant.CODE_NULL);
        }

        String codeFromRedis = redisCache.getCache("code");

        if (!code.equals(codeFromRedis)) {
            //验证码错误
            throw new VerificationCodeErrorException(MessageConstant.CODE_ERROR);
        }

        LambdaQueryWrapper<SysUser> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SysUser::getUserName, userName);
        SysUser sysUserFromMysql = sysUserMapper.selectOne(lqw);

        if (sysUserFromMysql == null) {
            //账号不存在
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        //密码比对
        if (!password.equals(sysUserFromMysql.getPassword())) {
            //密码错误
            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }

        //登录成功后，生成jwt令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.EMP_ID, sysUserFromMysql.getUserId());
        String token = JwtUtil.createJWT(
                jwtProperties.getUserSecretKey(),// 签名：huike
                jwtProperties.getUserTtl(), // 过期时间：7200000
                claims);

        LoginVo loginVo = new LoginVo();
        loginVo.setToken(token);
        loginVo.setUserId(sysUserFromMysql.getUserId());

        return Result.success(loginVo);
    }
}
